iconhelper: Handle invalidation
authorBenjamin Otte <otte@redhat.com>
Fri, 11 Dec 2015 14:12:19 +0000 (15:12 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 15 Dec 2015 13:41:16 +0000 (08:41 -0500)
When CSS, direction or scale factor change, handle the invalidation
inside the iconhelper.
This way the widgets using them don't have to.

gtk/gtkentry.c
gtk/gtkiconhelper.c
gtk/gtkiconhelperprivate.h
gtk/gtkimage.c

index 411abcad07eb3ece20b776921d9aace2c2504d07..7083adad257d73d62b1fcd38bdf1f8b2162dd97c 100644 (file)
@@ -5231,22 +5231,6 @@ gtk_entry_get_selection_bounds (GtkEditable *editable,
   return (priv->selection_bound != priv->current_pos);
 }
 
-static void
-icon_theme_changed (GtkEntry *entry)
-{
-  GtkEntryPrivate *priv = entry->priv;
-  gint i;
-
-  for (i = 0; i < MAX_ICONS; i++)
-    {
-      EntryIconInfo *icon_info = priv->icons[i];
-      if (icon_info != NULL) 
-        _gtk_icon_helper_invalidate (icon_info->icon_helper);
-    }
-
-  gtk_widget_queue_draw (GTK_WIDGET (entry));
-}
-
 static void
 gtk_entry_update_cached_style_values (GtkEntry *entry)
 {
@@ -5272,8 +5256,6 @@ gtk_entry_style_updated (GtkWidget *widget)
   GTK_WIDGET_CLASS (gtk_entry_parent_class)->style_updated (widget);
 
   gtk_entry_update_cached_style_values (entry);
-
-  icon_theme_changed (entry);
 }
 
 /* GtkCellEditable method implementations
index 1dcd6073320f2da7d88c1f1b6acaa58c9390e15e..bc82ee0a439a1b50b9e17a8c662a6ca6b77870b9 100644 (file)
@@ -27,6 +27,7 @@
 #include "gtkcssiconthemevalueprivate.h"
 #include "gtkcssnodeprivate.h"
 #include "gtkcssstyleprivate.h"
+#include "gtkcssstylepropertyprivate.h"
 #include "gtkiconthemeprivate.h"
 #include "gtkrendericonprivate.h"
 #include "deprecated/gtkiconfactoryprivate.h"
@@ -42,11 +43,20 @@ struct _GtkIconHelperPrivate {
   guint force_scale_pixbuf : 1;
 
   cairo_surface_t *rendered_surface;
-  gint last_surface_scale;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, gtk_icon_helper, GTK_TYPE_CSS_GADGET)
 
+static void
+gtk_icon_helper_invalidate (GtkIconHelper *self)
+{
+  if (self->priv->rendered_surface != NULL)
+    {
+      cairo_surface_destroy (self->priv->rendered_surface);
+      self->priv->rendered_surface = NULL;
+    }
+}
+
 static void
 gtk_icon_helper_take_definition (GtkIconHelper      *self,
                                  GtkImageDefinition *def)
@@ -59,7 +69,7 @@ gtk_icon_helper_take_definition (GtkIconHelper      *self,
   gtk_image_definition_unref (self->priv->def);
   self->priv->def = def;
 
-  _gtk_icon_helper_invalidate (self);
+  gtk_icon_helper_invalidate (self);
 }
 
 void
@@ -71,23 +81,40 @@ _gtk_icon_helper_clear (GtkIconHelper *self)
   self->priv->def = gtk_image_definition_new_empty ();
 
   self->priv->icon_size = GTK_ICON_SIZE_INVALID;
-  self->priv->last_surface_scale = 0;
 }
 
-void
-_gtk_icon_helper_invalidate (GtkIconHelper *self)
+static void
+gtk_icon_helper_style_changed (GtkCssGadget      *gadget,
+                               GtkCssStyleChange *change)
 {
-  if (self->priv->rendered_surface != NULL)
-    {
-      cairo_surface_destroy (self->priv->rendered_surface);
-      self->priv->rendered_surface = NULL;
-    }
+  if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON))
+    gtk_icon_helper_invalidate (GTK_ICON_HELPER (gadget));
+
+  GTK_CSS_GADGET_CLASS (gtk_icon_helper_parent_class)->style_changed (gadget, change);
+}
+
+static void
+gtk_icon_helper_constructed (GObject *object)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (object);
+  GtkWidget *widget;
+
+  widget = gtk_css_gadget_get_owner (GTK_CSS_GADGET (self));
+
+  g_signal_connect_swapped (widget, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self);
+  g_signal_connect_swapped (widget, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self);
+
+  G_OBJECT_CLASS (gtk_icon_helper_parent_class)->constructed (object);
 }
 
 static void
 gtk_icon_helper_finalize (GObject *object)
 {
   GtkIconHelper *self = GTK_ICON_HELPER (object);
+  GtkWidget *widget;
+
+  widget = gtk_css_gadget_get_owner (GTK_CSS_GADGET (self));
+  g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (gtk_icon_helper_invalidate), self);
 
   _gtk_icon_helper_clear (self);
   gtk_image_definition_unref (self->priv->def);
@@ -98,10 +125,13 @@ gtk_icon_helper_finalize (GObject *object)
 static void
 gtk_icon_helper_class_init (GtkIconHelperClass *klass)
 {
-  GObjectClass *oclass;
+  GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  
+  gadget_class->style_changed = gtk_icon_helper_style_changed;
 
-  oclass = G_OBJECT_CLASS (klass);
-  oclass->finalize = gtk_icon_helper_finalize;
+  object_class->constructed = gtk_icon_helper_constructed;
+  object_class->finalize = gtk_icon_helper_finalize;
 }
 
 static void
@@ -209,26 +239,6 @@ get_surface_size (GtkIconHelper   *self,
   cairo_destroy (cr);
 }
 
-static gboolean
-check_invalidate_surface (GtkIconHelper *self)
-{
-  int scale;
-
-  scale = gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)));
-
-  if ((self->priv->rendered_surface != NULL) &&
-      (self->priv->last_surface_scale == scale))
-    return FALSE;
-
-  self->priv->last_surface_scale = scale;
-
-  if (self->priv->rendered_surface)
-    cairo_surface_destroy (self->priv->rendered_surface);
-  self->priv->rendered_surface = NULL;
-
-  return TRUE;
-}
-
 static cairo_surface_t *
 ensure_surface_from_surface (GtkIconHelper   *self,
                              cairo_surface_t *orig_surface)
@@ -503,9 +513,6 @@ gtk_icon_helper_ensure_surface (GtkIconHelper *self)
 {
   int scale;
 
-  if (!check_invalidate_surface (self))
-    return;
-
   scale = gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)));
 
   self->priv->rendered_surface = gtk_icon_helper_load_surface (self, scale);
@@ -659,7 +666,7 @@ _gtk_icon_helper_set_icon_size (GtkIconHelper *self,
   if (self->priv->icon_size != icon_size)
     {
       self->priv->icon_size = icon_size;
-      _gtk_icon_helper_invalidate (self);
+      gtk_icon_helper_invalidate (self);
       return TRUE;
     }
   return FALSE;
@@ -672,7 +679,7 @@ _gtk_icon_helper_set_pixel_size (GtkIconHelper *self,
   if (self->priv->pixel_size != pixel_size)
     {
       self->priv->pixel_size = pixel_size;
-      _gtk_icon_helper_invalidate (self);
+      gtk_icon_helper_invalidate (self);
       return TRUE;
     }
   return FALSE;
@@ -685,7 +692,7 @@ _gtk_icon_helper_set_use_fallback (GtkIconHelper *self,
   if (self->priv->use_fallback != use_fallback)
     {
       self->priv->use_fallback = use_fallback;
-      _gtk_icon_helper_invalidate (self);
+      gtk_icon_helper_invalidate (self);
       return TRUE;
     }
   return FALSE;
@@ -812,7 +819,7 @@ _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
   if (self->priv->force_scale_pixbuf != force_scale)
     {
       self->priv->force_scale_pixbuf = force_scale;
-      _gtk_icon_helper_invalidate (self);
+      gtk_icon_helper_invalidate (self);
     }
 }
 
index 1f869d42a75cb7754611b2d44631ac9634771b38..fc3acf0c7b94fed36b5480b9d3e20a3fd1fbc46f 100644 (file)
@@ -72,7 +72,6 @@ GtkIconHelper *gtk_icon_helper_new (GtkCssNode *node,
                                     GtkWidget  *owner);
 
 void _gtk_icon_helper_clear (GtkIconHelper *self);
-void _gtk_icon_helper_invalidate (GtkIconHelper *self);
 
 gboolean _gtk_icon_helper_get_is_empty (GtkIconHelper *self);
 
index b8530b201f9e9c93f73a1495e60094629b42c2ab..c9b454c7376b4e2a68fd5073b4cefcdd636e1715 100644 (file)
@@ -191,8 +191,6 @@ static gboolean gtk_image_render_contents (GtkCssGadget *gadget,
                                            gpointer      data);
 
 static void gtk_image_style_updated        (GtkWidget    *widget);
-static void gtk_image_screen_changed       (GtkWidget    *widget,
-                                            GdkScreen    *prev_screen);
 static void gtk_image_finalize             (GObject      *object);
 static void gtk_image_reset                (GtkImage     *image);
 
@@ -205,8 +203,6 @@ static void gtk_image_get_property         (GObject      *object,
                                             GValue       *value,
                                             GParamSpec   *pspec);
 
-static void icon_theme_changed             (GtkImage     *image);
-
 enum
 {
   PROP_0,
@@ -253,7 +249,6 @@ gtk_image_class_init (GtkImageClass *class)
   widget_class->unmap = gtk_image_unmap;
   widget_class->unrealize = gtk_image_unrealize;
   widget_class->style_updated = gtk_image_style_updated;
-  widget_class->screen_changed = gtk_image_screen_changed;
 
   image_props[PROP_PIXBUF] =
       g_param_spec_object ("pixbuf",
@@ -1917,44 +1912,17 @@ gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
                                      minimum_baseline, natural_baseline);
 }
 
-static void
-icon_theme_changed (GtkImage *image)
-{
-  GtkImagePrivate *priv = image->priv;
-
-  _gtk_icon_helper_invalidate (priv->icon_helper);
-  gtk_widget_queue_draw (GTK_WIDGET (image));
-}
-
 static void
 gtk_image_style_updated (GtkWidget *widget)
 {
   GtkImage *image = GTK_IMAGE (widget);
   GtkImagePrivate *priv = image->priv;
-  GtkCssStyleChange *change;
 
   GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
 
-  change = gtk_style_context_get_change (gtk_widget_get_style_context (widget));
-  if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON))
-    icon_theme_changed (image);
   priv->baseline_align = 0.0;
 }
 
-static void
-gtk_image_screen_changed (GtkWidget *widget,
-                         GdkScreen *prev_screen)
-{
-  GtkImage *image;
-
-  image = GTK_IMAGE (widget);
-
-  if (GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed)
-    GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed (widget, prev_screen);
-
-  icon_theme_changed (image);
-}
-
 /**
  * gtk_image_set_pixel_size:
  * @image: a #GtkImage